package com.base.prototype.simple;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;

/**
 * 原型模式：定义原型
 */
public class ConcretePrototype implements Cloneable,Serializable {

	private int age;

	private String name;

	private ArrayList<String> list ;

	private Date date;

	private Test test;

	//可以看出来，不走构造函数，直接字节码复制
	public ConcretePrototype() {
		System.out.println("无参构造器");
	}

	public ConcretePrototype(int age, String name, ArrayList<String> list, Date date, Test test) {
		System.out.println("有参构造器");
		this.age = age;
		this.name = name;
		this.list = list;
		this.date = date;
		this.test = test;
	}

	//第三种：字节码复制
	public Object clone(){
		//深度克隆
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;
		try {
			//return super.clone();//默认浅克隆，只克隆八大基本数据类型和String
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this);

			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			ConcretePrototype copy = (ConcretePrototype)ois.readObject();
			//copy.birthday = new Date();
			return copy;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}finally{
			try {
				bos.close();
				oos.close();
				bis.close();
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


	//第二种：深拷贝
//	protected Object clone() throws CloneNotSupportedException {
//		ConcretePrototype prototype = null;
//		try {
//			prototype = (ConcretePrototype) super.clone();
//			prototype.list = (ArrayList) list.clone();
//			prototype.date = (Date) date.clone();
//			prototype.test=(Test) test.clone();
//			//克隆基于字节码的
//			//用反射，或者循环
//		} catch (Exception e) {
//		}
//		return prototype;
//	}

	//第一种： 浅拷贝
//	protected Object clone() throws CloneNotSupportedException {
//		return super.clone();
//	}


	//定义上100个属性

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ArrayList<String> getList() {
		return list;
	}

	public void setList(ArrayList<String> list) {
		this.list = list;
	}

	public Date getDate() {
		return date;
	}

	public Test getTest() {
		return test;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public void setTest(Test test) {
		this.test = test;
	}
}
	
	